package pdm.h_2011_01;

import java.io.StringReader;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;


/**
 * Afisez informatiile meteo despre orasul primit ca parametru prin intent
 * de la activitatea principala.
 * 
 * @author Vlase Paul
 *
 */
public class WeatherInfoActivity extends Activity {
	Intent intent_;
	TextView cityTV_;
	TextView forecastDateTV_;
	TextView currentConditionTV_;
	TextView currentTempcTV_;
	TextView currentHumidityTV_;
	ImageView currentIconIV_;
	TextView currentWindConditionTV_;
	TextView[] dayOfWeekTV_ = new TextView[4];
	TextView[] lowTV_ = new TextView[4];
	ImageView[] iconIV_ = new ImageView[4];
	TextView[] conditionTV_ = new TextView[4];

	ProgressDialog progressDialog_;

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.weather_info_activity);

		// Dialogul de asteptare
		progressDialog_ = ProgressDialog.show(this, "",
				"Loading. Please wait...", true, true);

		cityTV_ = (TextView) findViewById(R.id.cityTV);
		
		forecastDateTV_ = (TextView) findViewById(R.id.forecastDateTV);
		currentConditionTV_ = (TextView) findViewById(R.id.currentConditionTV);
		currentTempcTV_ = (TextView) findViewById(R.id.currentTempcTV);
		currentHumidityTV_ = (TextView) findViewById(R.id.currentHumidityTV);
		currentIconIV_ = (ImageView) findViewById(R.id.currentIconIV);
		currentWindConditionTV_ = (TextView) findViewById(R.id.currentWindConditionTV);

		dayOfWeekTV_[0] = (TextView) findViewById(R.id.dayOfWeekTV_0);
		lowTV_[0] = (TextView) findViewById(R.id.low_0);
		iconIV_[0] = (ImageView) findViewById(R.id.iconIV_0);
		conditionTV_[0] = (TextView) findViewById(R.id.conditionTV_0);

		dayOfWeekTV_[1] = (TextView) findViewById(R.id.dayOfWeekTV_1);
		lowTV_[1] = (TextView) findViewById(R.id.low_1);
		iconIV_[1] = (ImageView) findViewById(R.id.iconIV_1);
		conditionTV_[1] = (TextView) findViewById(R.id.conditionTV_1);

		dayOfWeekTV_[2] = (TextView) findViewById(R.id.dayOfWeekTV_2);
		lowTV_[2] = (TextView) findViewById(R.id.low_2);
		iconIV_[2] = (ImageView) findViewById(R.id.iconIV_2);
		conditionTV_[2] = (TextView) findViewById(R.id.conditionTV_2);

		dayOfWeekTV_[3] = (TextView) findViewById(R.id.dayOfWeekTV_3);
		lowTV_[3] = (TextView) findViewById(R.id.low_3);
		iconIV_[3] = (ImageView) findViewById(R.id.iconIV_3);
		conditionTV_[3] = (TextView) findViewById(R.id.conditionTV_3);

		intent_ = getIntent();
		this.downloadXml(intent_.getStringExtra("city"));

		progressDialog_.dismiss();
	}

	/**
	 * Metoda downloadeaza fisierul xml ce contine datele meteo despre un oras,
	 * il parseaza si afiseaza doar datele necesare in activitate.
	 * 
	 * @param city - numele orasului
	 */	
	public void downloadXml(String city) {
		int resID;

		cityTV_.setText("City : " + city);

		String url = "http://www.google.com/ig/api?weather=" + city;
		url = url.replace(" ", "%20");

		HttpGet getMethod = new HttpGet(url);
		HttpClient client = new DefaultHttpClient();

		try {
			ResponseHandler<String> responseHandler = new BasicResponseHandler();
			// ResponseBody reprezinta continutul fisierului RSS luat de pe
			// Internet
			String responseBody = client.execute(getMethod, responseHandler);


			if (responseBody.indexOf("problem_cause") == -1) {

				DocumentBuilderFactory factory = DocumentBuilderFactory
						.newInstance();
				DocumentBuilder builder = factory.newDocumentBuilder();
				InputSource is = new InputSource(new StringReader(responseBody));
				Document doc = builder.parse(is);

				doc.getDocumentElement().normalize();

				NodeList forecastConditionsNodeList;
				NodeList weatherNodeList;
				NodeList nodeList;
				Element node;
				Element forecastConditionsNode;
				Element weatherNode;
				Element currentConditionsNode;
				String data;

				weatherNodeList = doc.getElementsByTagName("weather");
				weatherNode = (Element) weatherNodeList.item(0);
				nodeList = weatherNode
						.getElementsByTagName("forecast_information");
				node = (Element) nodeList.item(0);
				nodeList = node.getElementsByTagName("forecast_date");
				node = (Element) nodeList.item(0);
				data = node.getAttribute("data");

				forecastDateTV_.setText("Date : " + data);

				weatherNode = (Element) weatherNodeList.item(0);
				nodeList = weatherNode
						.getElementsByTagName("current_conditions");
				currentConditionsNode = (Element) nodeList.item(0);
				nodeList = currentConditionsNode
						.getElementsByTagName("condition");
				node = (Element) nodeList.item(0);
				data = node.getAttribute("data");

				currentConditionTV_.setText("Condition : " + data);

				nodeList = currentConditionsNode.getElementsByTagName("temp_c");
				node = (Element) nodeList.item(0);
				data = node.getAttribute("data");

				currentTempcTV_.setText("Temp : " + data + " C");

				nodeList = currentConditionsNode
						.getElementsByTagName("humidity");
				node = (Element) nodeList.item(0);
				data = node.getAttribute("data");

				currentHumidityTV_.setText(data);

				nodeList = currentConditionsNode.getElementsByTagName("icon");
				node = (Element) nodeList.item(0);
				data = node.getAttribute("data");

				data = data.substring(19, data.length() - 4);
				resID = getResources().getIdentifier(data, "drawable",
						getPackageName());

				currentIconIV_.setImageResource(resID);

				nodeList = currentConditionsNode
						.getElementsByTagName("wind_condition");
				node = (Element) nodeList.item(0);
				data = node.getAttribute("data");

				currentWindConditionTV_.setText(data);

				forecastConditionsNodeList = weatherNode
						.getElementsByTagName("forecast_conditions");

				for (int i = 0; i < 4; i++) {
					forecastConditionsNode = (Element) forecastConditionsNodeList
							.item(i);
					nodeList = forecastConditionsNode
							.getElementsByTagName("day_of_week");
					node = (Element) nodeList.item(0);
					data = node.getAttribute("data");

					dayOfWeekTV_[i].setText("Day of week : " + data);

					forecastConditionsNode = (Element) forecastConditionsNodeList
							.item(i);
					nodeList = forecastConditionsNode
							.getElementsByTagName("low");
					node = (Element) nodeList.item(0);
					data = node.getAttribute("data");

					// C = (F - 32) * 5 / 9
					lowTV_[i].setText("Low : " + (Integer.parseInt(data) - 32)
							* 5 / 9 + " C");

					forecastConditionsNode = (Element) forecastConditionsNodeList
							.item(i);
					nodeList = forecastConditionsNode
							.getElementsByTagName("icon");
					node = (Element) nodeList.item(0);
					data = node.getAttribute("data");

					data = data.substring(19, data.length() - 4);
					resID = getResources().getIdentifier(data, "drawable",
							getPackageName());

					iconIV_[i].setImageResource(resID);

					forecastConditionsNode = (Element) forecastConditionsNodeList
							.item(i);
					nodeList = forecastConditionsNode
							.getElementsByTagName("condition");
					node = (Element) nodeList.item(0);
					data = node.getAttribute("data");

					conditionTV_[i].setText("Condition : " + data);
				}
			} else {
				// Am introdus un nume de oras gresit
				AlertDialog.Builder builder = new AlertDialog.Builder(this);
				builder.setTitle("Error").setMessage("Wrong city name")
						.setCancelable(true);

				AlertDialog alert = builder.create();
				alert.setOnCancelListener(new myCancelListener(this));
				progressDialog_.dismiss();

				alert.show();

			}
		} 
		catch (Exception e) {
			// A aparut o eroare la conectare la serviciul Google Weather
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setTitle("Error").setMessage("Connection error")
					.setCancelable(true);

			AlertDialog alert = builder.create();
			alert.setOnCancelListener(new myCancelListener(this));
			progressDialog_.dismiss();

			alert.show();
		}

	}
}


/**
 * Listener pentru apasarea pe butonul de "Back" la afisarea unui dialog de
 * eroare. Pentru a nu observa utilizatorul ca se revine la activitatea
 * WeatherInfo, la inchiderea dialog-ului se inchide si activitatea, si se
 * revine in MainActivity.
 * 
 * @author Vlase Paul
 *
 */
class myCancelListener implements DialogInterface.OnCancelListener {

	Activity activity_;

	public myCancelListener(Activity activity) {
		activity_ = activity;
	}

	public void onCancel(DialogInterface dialog) {
		activity_.finish();
	}
}
